﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;

using Eneta.Portal.Common;
using Eneta.Portal.Common.Dto;
using Eneta.Portal.Common.Helpers;
using Eneta.Portal.Common.Repository;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;

namespace Eneta.Portal.NewsAndBlogs.Pages
{
    public class AnnouncementView : Page
    {
        protected HtmlAnchor profileLink;
        protected HtmlImage profileImage;
        protected HtmlAnchor authorLink;
        protected HtmlGenericControl publishDate;
        protected HtmlAnchor titleLink;
        protected HtmlGenericControl summaryField;
        protected HtmlGenericControl CommandButtons;
        protected HtmlGenericControl promoBox;
        protected HtmlGenericControl Body;
        protected PlaceHolder AddButtons;
        

        protected HtmlGenericControl ReadOnlyKeywordsContainer;
        protected Repeater ReadOnlyKeywordsRepeater;
        protected HtmlGenericControl CompanyContainer;
        protected HtmlAnchor CompanyLink;

        protected Label StatusLabel;
        protected HtmlGenericControl AcceptPostingContainer;
        protected Repeater keywordGroupsRepeater;
        protected TextBox rejectReasonField;
        protected Button ChangeEntry;
        protected Button AcceptEntry;
        protected Button RejectEntry;

        protected HtmlGenericControl CommentsCount;
        protected Repeater CommentsRepeater;
        protected HtmlGenericControl AddCommentContainer;
        protected HtmlAnchor AddCommentProfileLink;
        protected HtmlImage AddCommentProfileImage;
        protected HtmlAnchor AddCommentProfileNameLink;

        protected TextBox CommentField;
        protected Button SubmitComment;

        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);

            ReadOnlyKeywordsRepeater.ItemDataBound += ReadOnlyKeywordsRepeaterItemDataBound;
            CommentsRepeater.ItemDataBound += CommentsRepeaterItemDataBound;
            SubmitComment.Click += SubmitCommentClick;
            ChangeEntry.Click += ChangeEntryClick;
            AcceptEntry.Click += AcceptEntryClick;
            RejectEntry.Click += RejectEntryClick;
            keywordGroupsRepeater.ItemDataBound += KeywordGroupsRepeaterItemDataBound;
        }

        private void ChangeEntryClick(object sender, EventArgs e)
        {
            Response.Redirect("/uudised/teated/AddAnnouncement.aspx?ID=" + Announcement.Id + "&Owner="+Announcement.OwnerProfileId);
        }

        protected void KeywordGroupsRepeaterItemDataBound(object sender, RepeaterItemEventArgs e)
        {
            if (e.Item.DataItem == null)
                return;

            var groupName = (string)e.Item.DataItem;

            var groupNameLabel = (Label)e.Item.FindControl("groupNameLabel");
            groupNameLabel.Text = groupName;

            var keywordCheckList = (CheckBoxList)e.Item.FindControl("KeywordCheckList");

            var query = from k in GetAllKeywords()
                        where k.GroupName == groupName
                        orderby k.Title
                        select k;
            keywordCheckList.DataSource = query;
            keywordCheckList.DataBind();

            foreach (ListItem item in keywordCheckList.Items)
            {
                var keywordId = int.Parse(item.Value);
                item.Selected = Announcement.Keywords.Exists(p => p.Id == keywordId);
            }
        }

        protected void ReadOnlyKeywordsRepeaterItemDataBound(object sender, RepeaterItemEventArgs e)
        {
            if (e.Item.DataItem == null)
                return;

            var keyword = (Common.Dto.KeywordDto)e.Item.DataItem;
            var keywordLink = (HtmlAnchor)e.Item.FindControl("KeywordLink");
            keywordLink.InnerText = keyword.Title;
        }

        protected void RejectEntryClick(object sender, EventArgs e)
        {
            AcceptItem(false);
            Response.Redirect(Request.RawUrl);
        }

        protected void AcceptEntryClick(object sender, EventArgs e)
        {
            AcceptItem(true);
            Response.Redirect(Request.RawUrl);
        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            int id;
            if(!int.TryParse(Request.QueryString["ID"], out id))
            {
                Response.Redirect("/uudised/teated/");
                return;
            }

            var repository = new AnnouncementRepository(SPContext.Current.Web);
            var ann = repository.GetAnnouncementById(id);

            if(ann==null)
            {
                Response.Redirect("/uudised/teated/");
                return;
            }

            Response.Redirect("/uudised/teated/Lehed/" + ann.FileName);
            return;

            if (IsPostBack)
                return;

            if (Announcement == null)
            {
                AddCommentContainer.Visible = false;
                return;
            }

            Body.Visible = true;
            if (SPContext.Current.Web.CurrentUser != null)
            {
                if (AddButtons != null)
                    AddButtons.Visible = true;
            }
            if (CommandButtons != null)
                CommandButtons.Visible = CurrentUserIsAdmin; 
            profileLink.HRef = "/profile.aspx?ID=" + Announcement.OwnerProfileId;
            profileImage.Src = "/_layouts/enetahandlers/userimagehandler.ashx?size=32&id=" + Announcement.OwnerProfileId;
            authorLink.HRef = profileLink.HRef;
            authorLink.InnerText = Announcement.OwnerUserName;
            publishDate.InnerText = Announcement.Created.ToShortDateString();
            titleLink.HRef = Announcement.DisplayUrl;
            titleLink.InnerText = Announcement.Title;
            
            //summaryField.InnerHtml = Announcement.Body.Replace("\n", "<br/>");
            //summaryField.InnerHtml = RegExHelper.DetectAndReplaceUrls(summaryField.InnerHtml);
            summaryField.InnerHtml = RegExHelper.RemoveForbiddenAttributes(Announcement.Body);

            CommentsCount.InnerText = Announcement.Comments.Count.ToString();
            CommentsRepeater.DataSource = Announcement.Comments;
            CommentsRepeater.DataBind();
            
            AcceptPostingContainer.Visible = false;

            var currentUser = SPContext.Current.Web.CurrentUser;
            SPListItem profileItem = null;

            AddCommentContainer.Visible = false;
            if (currentUser != null)
            {
                profileItem = currentUser.GetUserProfile();
                if (profileItem != null)
                {
                    AddCommentContainer.Visible = true;
                }
            }

            ReadOnlyKeywordsContainer.Visible = false;
            if (currentUser != null && currentUser.IsSiteAdmin)
            {
                AcceptPostingContainer.Visible = true;
                var query = from k in GetAllKeywords()
                            orderby k.GroupName
                            select k.GroupName;
                if (query.Count() > 0)
                {
                    keywordGroupsRepeater.DataSource = query.Distinct();
                    keywordGroupsRepeater.DataBind();
                }
                if (Announcement.Status == SPModerationStatusType.Approved)
                    StatusLabel.Text = "Kinnitatud";
                else if (Announcement.Status == SPModerationStatusType.Denied)
                    StatusLabel.Text = "Tagasilükatud";
                else
                    StatusLabel.Text = "Ootel";

            }
            else
            {
                ReadOnlyKeywordsContainer.Visible = true;
                ReadOnlyKeywordsRepeater.DataSource = Announcement.Keywords;
                ReadOnlyKeywordsRepeater.DataBind();
            }

            if (profileItem != null)
            {
                AddCommentContainer.Visible = true;
                AddCommentProfileLink.HRef = "/profile.aspx?ID=" + profileItem.ID;
                AddCommentProfileLink.Title = currentUser.Name;
                AddCommentProfileImage.Src = "/_layouts/enetahandlers/userimagehandler.ashx?size=32&id=" +
                                             profileItem.ID;
                AddCommentProfileImage.Alt = currentUser.Name;
                AddCommentProfileNameLink.HRef = AddCommentProfileLink.HRef;
                AddCommentProfileNameLink.Title = AddCommentProfileLink.Title;
                AddCommentProfileNameLink.InnerText = AddCommentProfileLink.Title;

                string promoText =
                    "<p>{0} <a href='/uudised/teated/AddAnnouncement.aspx'>kirjuta uudis</a> või <a href='/addblog.aspx'>lisa oma blogi</a>.</p>";
                promoText = string.Format(promoText, profileItem.Name);
                promoBox.InnerHtml = promoText;
            }

            if(Announcement.Companies != null)
                if(Announcement.Companies.Count > 0)
                {
                    var company = Announcement.Companies[0];
                    CompanyLink.HRef = "/firmad/Lehed/" + company.FileName;
                    CompanyLink.InnerText = company.Title;
                }

            if(string.IsNullOrEmpty(CompanyLink.HRef))
            {
                CompanyContainer.Visible = false;
            }

            ReadOnlyKeywordsContainer.Visible = (Announcement.Keywords.Count > 0);
        }

        private AnnouncementDto _announcement;

        protected AnnouncementDto Announcement
        {
            get
            {
                if (_announcement != null)
                    return _announcement;

                _announcement = GetCurrentPost();
                //_post.Comments = GetComments(_post);
                return _announcement;
            }
        }

        protected void CommentsRepeaterItemDataBound(object sender, RepeaterItemEventArgs e)
        {
            if (e.Item.DataItem == null)
                return;

            var comment = (CommentDto)e.Item.DataItem;
            var commentProfileLink = (HtmlAnchor)e.Item.FindControl("CommentProfileLink");
            var commentProfileImage = (HtmlImage)e.Item.FindControl("CommentProfileImage");
            var commentBody = (HtmlGenericControl)e.Item.FindControl("CommentBody");
            var commentProfileNameLink = (HtmlAnchor)e.Item.FindControl("CommentProfileNameLink");
            var commentTime = (HtmlGenericControl)e.Item.FindControl("CommentTime");

            commentProfileLink.HRef = "/profile.aspx?ID=" + comment.OwnerProfileId;
            commentProfileLink.Title = comment.OwnerName;
            commentProfileImage.Src = "/_layouts/enetahandlers/userimagehandler.ashx?size=32&id=" + comment.OwnerProfileId;
            commentProfileImage.Alt = comment.OwnerName;

            commentBody.InnerHtml = comment.Body.Replace("\n", "<br/>");
            commentProfileNameLink.HRef = commentProfileLink.HRef;
            commentProfileNameLink.Title = commentProfileLink.Title;
            commentProfileNameLink.InnerText = commentProfileLink.Title;
            commentTime.InnerText = comment.Created.ToString();
        }

        protected void SubmitCommentClick(object sender, EventArgs e)
        {
            var siteId = SPContext.Current.Site.ID;
            var userName = SPContext.Current.Web.CurrentUser.LoginName;

            var sec = new SPSecurity.CodeToRunElevated(delegate
            {
                using (var site = new SPSite(siteId))
                {
                    using (var web = site.OpenWeb("/uudised/teated/"))
                    {
                        var list = web.Lists["Comments"];
                        var item = list.Items.Add();
                        item["Comment"] = CommentField.Text;

                        var authorFieldId = item.Fields.GetFieldByInternalName("Author").Id;
                        item[authorFieldId] = web.SiteUsers[userName];

                        var pageValue = new SPFieldLookupValue(Announcement.Id, Announcement.Title);
                        item["NewsPage"] = pageValue;

                        item.Update();
                        list.Update();
                    }
                }
            });
            SPSecurity.RunWithElevatedPrivileges(sec);
            Response.Redirect(Request.RawUrl, true);
        }

        private AnnouncementDto GetCurrentPost()
        {
            var idString = Request.QueryString["ID"];
            if (string.IsNullOrEmpty(idString))
            {
                Logger.LogInfo("GetCurrentPost(): idString is null", GetType().ToString());
                return null;
            }

            int id;
            if (!int.TryParse(idString, out id))
            {
                Logger.LogInfo("GetCurrentPost(): idString is not numeric", GetType().ToString());
                return null;
            }

            if (id < 1)
            {
                Logger.LogInfo("GetCurrentPost(): id is less than one", GetType().ToString());
                return null;
            }

            var repository = new AnnouncementRepository(SPContext.Current.Web);
            var currentUser = SPContext.Current.Web.CurrentUser;
            AnnouncementDto announcement;
            if (currentUser == null)
            {
                Logger.LogInfo("GetCurrentPost(): currentUser is null", GetType().ToString());
                announcement = repository.GetPublicAnnouncementById(id);
            }
            else if (currentUser.IsSiteAdmin)
            {
                Logger.LogInfo("GetCurrentPost(): currentUser is site admin", GetType().ToString());
                announcement = repository.GetAnnouncementById(id);
            }
            else
                announcement = repository.GetPublicAnnouncementById(id);

            return announcement;
        }

        /*private static List<PostCommentDto> GetComments(BlogPostDto post)
        {
            var comments = new List<PostCommentDto>();
            if (post == null)
                return comments;
            if (post.ID <= 0)
                return comments;

            var siteId = SPContext.Current.Site.ID;

            var sec = new SPSecurity.CodeToRunElevated(delegate
            {
                using (var site = new SPSite(siteId))
                {
                    using (var web = site.OpenWeb("/uudised/teated/"))
                    {
                        var list = web.Lists["Comments"];

                        var queryString = "<Where><Eq><FieldRef Name='NewsPage' LookupId='True' /><Value Type='Lookup'>{0}</Value></Eq></Where>";
                        queryString += "<OrderBy><FieldRef Name='Created' Ascending='True' /></OrderBy>";
                        queryString = string.Format(queryString, post.ID);
                        var query = new SPQuery {Query = queryString};

                        var items = list.GetItems(query);
                        if (items == null)
                            return;
                        if (items.Count == 0)
                            return;

                        foreach (SPListItem item in items)
                        {
                            var comment = new PostCommentDto();

                            var authorFieldId = item.Fields.GetFieldByInternalName("Author").Id;
                            var authorValue = new SPFieldUserValue(web, item[authorFieldId].ToString());
                            var author = authorValue.User;

                            comment.AuthorName = author.Name;
                            var profileItem = author.GetUserProfile();
                            if (profileItem != null)
                                comment.AuthorProfileId = profileItem.ID.ToString();

                            var createdFieldId = item.Fields.GetFieldByInternalName("Created").Id;
                            comment.Created = (DateTime)item[createdFieldId];
                            if (item["Comment"] != null)
                                comment.Comment = item["Comment"].ToString();
                            comment.Post = post;

                            comments.Add(comment);
                        }
                    }
                }
            });
            SPSecurity.RunWithElevatedPrivileges(sec);
            return comments;
        }
        */

        private List<KeywordDto> _allKeywords;
        private List<KeywordDto> GetAllKeywords()
        {
            if (_allKeywords != null)
                return _allKeywords;

            var keywords = new List<KeywordDto>();
            var siteId = SPContext.Current.Site.ID;

            var sec = new SPSecurity.CodeToRunElevated(delegate
            {
                using (var site = new SPSite(siteId))
                {
                    using (var web = site.OpenWeb())
                    {
                        var list = web.Lists["Keywords"];
                        var items = list.Items;

                        if (items == null)
                            return;
                        if (items.Count < 1)
                            return;


                        foreach (SPListItem item in items)
                        {
                            var lookup = new KeywordDto
                                             {
                                                 Id = item.ID, 
                                                 Title = item.Title
                                             };
                            if (item["KeywordGroup"] != null)
                                lookup.GroupName = item["KeywordGroup"].ToString();
                            keywords.Add(lookup);
                        }
                    }
                }
            });
            SPSecurity.RunWithElevatedPrivileges(sec);

            _allKeywords = keywords;
            return _allKeywords;
        }

        private void AcceptItem(bool accept)
        {
            var siteId = SPContext.Current.Site.ID;

            //var sec = new SPSecurity.CodeToRunElevated(delegate
            //{
                using (var site = new SPSite(siteId))
                {
                    using (var web = site.OpenWeb("/uudised/teated"))
                    {
                        var list = web.Lists["Lehed"];
                        var item = list.GetItemById(Announcement.Id);

                        var activity = new AdminActivityDto();
                        activity.PreviousEditor = new SPFieldUserValue(SPContext.Current.Web, item["Editor"].ToString()).User.LoginName;
                        activity.PreviousStatus = item.ModerationInformation.Status;
                        activity.PreviousTimeStamp = (DateTime)item["Modified"];
                        activity.Module = "Announcements";
                        activity.Url = Request.RawUrl;

                        if (accept)
                        {
                            var keywords = new SPFieldLookupValueCollection();
                            item.File.CheckOut();

                            foreach (RepeaterItem groupItem in keywordGroupsRepeater.Items)
                            {
                                var checkList = (CheckBoxList)groupItem.FindControl("KeywordCheckList");
                                if (checkList == null)
                                    continue;

                                foreach (ListItem checkItem in checkList.Items)
                                {
                                    if (!checkItem.Selected)
                                        continue;
                                    var id = int.Parse(checkItem.Value);
                                    var text = checkItem.Text;
                                    var keyword = new SPFieldLookupValue(id, text);
                                    keywords.Add(keyword);
                                }
                            }
                            if (keywords.Count > 0)
                                item["Keywords"] = keywords;
                            item.Update();
                            //list.Update();

                            item.File.CheckIn(string.Empty, SPCheckinType.MajorCheckIn);
                            item.File.Update();

                            
                        }
                        

                        //var page = PublishingPage.GetPublishingPage(item);
                        if (accept)
                        {
                            if(item.ModerationInformation.Status != SPModerationStatusType.Approved)
                            {
                                var ownerValue = new SPFieldUserValue(web, item["RealAuthor"].ToString());
                                var owner = ownerValue.User;
                                var blogLink = "http://www.eneta.ee/uudised/teated/AnnouncementView.aspx?ID=" + item.ID;
                                var body = "<html><body style='font-family:arial;font-size:10pt'><p>Hei " + owner.Name + "!</p>";
                                body += "<p>Sinu lisatud teade \"" + item.Title + "\" on edukalt avaldatud Eneta portaalis. ";
                                body += "Otselink teatele <a href=\"" + blogLink + "\">" + blogLink + "</a>";
                                body += "</p>";

                                body += "<p>Tervitustega,<br/>";
                                body += "Eneta tiim</p>";
                                body += "<a href=\"http://www.eneta.ee\"><img src=\"http://www.eneta.ee/SiteCollectionImages/logod/eneta_logo_250x78_sinine.png\" border=\"0\"></a>";
                                body += "</body></html>";

                                SPUtility.SendEmail(web, false, false, owner.Email, owner.Name + ", Sinu teade avaldati Eneta portaalis", body);
                                SPUtility.SendEmail(web, false, false, "abi@eneta.ee", owner.Name + ", Sinu teade avaldati Eneta portaalis", body);
                    
                            }
                            item.File.Approve(string.Empty);
                            activity.CurrentStatus = SPModerationStatusType.Approved;
                        }
                        else
                        {
                            if (rejectReasonField != null)
                            {
                                if (string.IsNullOrEmpty(rejectReasonField.Text))
                                    item.File.Deny(string.Empty);
                                else 
                                    item.File.Deny(rejectReasonField.Text);

                                activity.CurrentStatus = SPModerationStatusType.Denied;
                            }
                        }

                        activity.CurrentEditor = new SPFieldUserValue(SPContext.Current.Web, item["Editor"].ToString()).User.LoginName;                        
                        activity.CurrentTimeStamp = (DateTime)item["Modified"];
                        ActivityLogger.LogActivity(activity);
                    }
                }
            //});
            //SPSecurity.RunWithElevatedPrivileges(sec);
        }

        private bool CurrentUserIsAdmin
        {
            get
            {
                var user = SPContext.Current.Web.CurrentUser;
                if (user == null)
                    return false;

                return user.IsSiteAdmin;
            }
        }
    }
}
